<?php
declare(strict_types=1);

namespace App\Service;

use App\Model\Dao\RiskRuleParamDao;
use App\Model\Enum\RiskRuleActionEnum;
use App\Model\Enum\RiskRuleProcessTypeEnum;
use App\Utils\CustomUtils;
use App\Utils\StringUtils;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\RiskRuleInfoDao;
use App\Exception\XZXValidationException;
use App\Constants\XZXResponseCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Coroutine;
use App\Utils\DateUtils;
use Hyperf\Utils\Arr;
use parallel\Sync;

class RiskRuleInfoService {

    /**
     * @Inject()
     * @var RiskRuleInfoDao
     */
    private $RiskRuleInfoDao;

    /**
     * @Inject()
     * @var RiskRuleParamDao
     */
    private $RiskRuleParamDao;

    /**
     * @Inject()
     * @var SyncService
     */
    private $SyncService;

    /**
     * 列表
     *
     * @param array $param
     *
     * @return array
     */
    public function list (array $param) {

        $limit = $param['limit'];
        $page  = $param['page'];

        $total = $this->RiskRuleInfoDao->getCount($param);
        $list  = $this->RiskRuleInfoDao->getList($param, $page, $limit);

        $list = CustomUtils::formatCreateTime($list);

        foreach ($list as $k => $v) {
            // $v['createTime'] = xeGetDateTime($v['createTime']);
            $v['strStatus']  = $this->RiskRuleInfoDao->strStatus($v['status']);
            $list[$k] = $v;
        }

        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 详情
     *
     * @param $param
     *
     * @return array
     */
    public function get ($param) {

        $info = $this->RiskRuleInfoDao->get($param['id']);

        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $info['param'] = $this->RiskRuleParamDao->get($info['paramId']);

        $info = CustomUtils::formatCreateTime($info);
        $info['param']  = CustomUtils::formatCreateTime($info['param']);

        $data = $info;

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 从参数过滤得到添加/更新数组
     *
     * @param $param
     *
     * @return array
     */
    protected function _filterUpdate ($param) {

        $update = Arr::only($param, [
            'status',
            'ruleName',
            'processType',
            'paramId',
        ]);

        return $update;
    }

    protected function _verifyParamIdOrFail ($paramId) {

        $info = $this->RiskRuleParamDao->getWhere([
            'id'     => $paramId,
        ]);

        if (!$info) {
            throw new \Exception("paramId 无效");
        }
    }

    /**
     * 添加
     *
     * @param $param
     *
     * @return array
     * @throws \Throwable
     */
    public function add ($param) {

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['createBy', 'updateBy']));

        $update['id'] = StringUtils::uuidV4();

        $this->_verifyParamIdOrFail($update['paramId']);

        $this->RiskRuleInfoDao->insert($update);

        $data = ['id' => $update['id']];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 编辑
     *
     * @param $param
     *
     * @return array
     */
    public function edit ($param) {

        $id = Arr::pull($param, 'id');

        $info = $this->RiskRuleInfoDao->get($id);
        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['updateBy']));

        $this->_verifyParamIdOrFail($update['paramId']);

        $this->RiskRuleInfoDao->update($id, $update);

        // 刷新缓存
        $this->SyncService->syncRiskRuleInfo($id);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    /**
     * 删除
     *
     * @param $param
     *
     * @return array
     */
    public function del ($param) {

        $id = Arr::pull($param, 'id');

        $result = $this->RiskRuleInfoDao->get($id);

        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $this->RiskRuleInfoDao->del($id, false);

        // 刷新缓存
        $this->SyncService->syncRiskRuleInfo($id);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    public function getOption(array $param) {
        $result = $this->RiskRuleInfoDao->getOption($param['search']);
        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $result);
    }

    public function processTypeOptions (array $param) {
        $data = RiskRuleProcessTypeEnum::born()->getOptions();
        return CustomUtils::buildSuccess($data);
    }

    public function actionOptions (array $param) {
        $data = RiskRuleActionEnum::born()->getOptions();
        return CustomUtils::buildSuccess($data);
    }

}
